package com.xjoyt.pay.master.services;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xjoyt.pay.abstracts.AbstractService;
import com.xjoyt.pay.annotations.LockMethod;
import com.xjoyt.pay.annotations.LockParam;
import com.xjoyt.pay.commons.ObjectUtils;
import com.xjoyt.pay.dto.ExecuteResult;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.master.params.MerchantPageParam;
import com.xjoyt.pay.master.po.CompanyPreference;
import com.xjoyt.pay.master.po.Merchant;
import com.xjoyt.pay.master.po.MerchantRate;
import com.xjoyt.pay.master.repository.CompanyPreferenceRepository;
import com.xjoyt.pay.master.repository.DistributorRepository;
import com.xjoyt.pay.master.repository.MerchantRateRepository;
import com.xjoyt.pay.master.repository.MerchantRepository;
import com.xjoyt.pay.share.interfaces.FileObejctContract;
import com.xjoyt.pay.share.po.FileObejct;

@Service
public class MerchantService extends AbstractService {

	@Autowired
	private MerchantRepository repository;

	@Autowired
	private MerchantRateRepository merchantRateRepository;

	@Autowired
	private DistributorRepository distributorRepository;

	@Autowired
	private CompanyPreferenceRepository companyPreferenceRepository;

	@Autowired
	private FileObejctContract fileObejctContract;

	public Merchant get(String id) {
		return repository.findOne(id);
	}

	public List<MerchantRate> getMerchantRate(String id) {
		return merchantRateRepository.findAllByMerchantId(id);
	}

	public ExecuteResult<String> resetKey(String id) {
		Merchant entity = repository.findOne(id);
		if (entity == null) {
			return ExecuteResult.fail("数据不存在");
		}
		entity.key = UUID.randomUUID().toString().replace("-", StringUtils.EMPTY);
		repository.save(entity);
		return ExecuteResult.ok(entity.key);
	}

	public Merchant getByNo(String no) {
		return repository.findOneByNo(no);
	}

	@LockMethod(block = true)
	public ExecuteResult<?> update(@LockParam("id") com.xjoyt.pay.merchant.register.po.Merchant param) {
		Merchant merchant = repository.findOne(param.id);
		if (merchant == null) {
			merchant = new Merchant();
		}

		// 克隆之前先保存属性
		ObjectUtils.fieldCopy(param, merchant);
		if (merchant.distributor == null) {
			merchant.distributor = distributorRepository.findOne(param.distributor.id);
		}

		if (StringUtils.isBlank(merchant.no)) {
			CompanyPreference preference = companyPreferenceRepository.findOne(param.distributor.companyId);
			merchant.no = preference == null || StringUtils.isBlank(preference.merchantPrefix) ? StringUtils.EMPTY
					: preference.merchantPrefix.toUpperCase();
			merchant.no += createMerchantNo();
		}
		merchant.enabled = true;
		if (StringUtils.isBlank(merchant.key)) {
			merchant.key = UUID.randomUUID().toString().replaceAll("-", StringUtils.EMPTY);
		}
		merchant = repository.save(merchant);

		// 储存照片
		ExecutorService threadPool = Executors.newCachedThreadPool();
		FutureTask<Object> future = new FutureTask<>(() -> {
			saveImage(param);
			return null;
		});
		threadPool.execute(future);

		return ExecuteResult.ok();
	}

	/**
	 * 储存照片
	 * 
	 * @param param
	 */
	private void saveImage(com.xjoyt.pay.merchant.register.po.Merchant param) {
		List<FileObejct> list = new ArrayList<>();
		if (StringUtils.isNotBlank(param.accountLicenseImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "accountLicenseImageUrl";
			po.key = param.id;
			po.remark = "开户许可证照片";
			po.path = param.accountLicenseImageUrl;
		}
		if (StringUtils.isNotBlank(param.bankCardImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "bankCardImageUrl";
			po.key = param.id;
			po.remark = "银行卡照片";
			po.path = param.bankCardImageUrl;
		}
		if (StringUtils.isNotBlank(param.facadeImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "facadeImageUrl";
			po.key = param.id;
			po.remark = "门面照片";
			po.path = param.facadeImageUrl;
		}
		if (StringUtils.isNotBlank(param.identityCardBackImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "identityCardBackImageUrl";
			po.key = param.id;
			po.remark = "身份证背面照片";
			po.path = param.identityCardBackImageUrl;
		}
		if (StringUtils.isNotBlank(param.identityCardFrontImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "identityCardFrontImageUrl";
			po.key = param.id;
			po.remark = "身份证正面照片";
			po.path = param.identityCardFrontImageUrl;
		}
		if (StringUtils.isNotBlank(param.identityCardImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "identityCardImageUrl";
			po.key = param.id;
			po.remark = "手持身份证照片";
			po.path = param.identityCardImageUrl;
		}
		if (StringUtils.isNotBlank(param.licenseImageUrl)) {
			FileObejct po = new FileObejct();
			list.add(po);
			po.property = "licenseImageUrl";
			po.key = param.id;
			po.remark = "营业执照照片";
			po.path = param.licenseImageUrl;
		}

		fileObejctContract.saveAllUrl(list);
	}

	private String createMerchantNo() {
		Long count = repository.getLastNo();
		return StringUtils.leftPad(String.valueOf(++count), 15, "0");
	}

	public PageResult<Merchant> loadPage(PageParam<MerchantPageParam> param) {
		return repository.loadPage(param);
	}

	public Merchant getByCustomerNo(String distributorId, String no) {
		return repository.findOneByDistributorIdAndOutNo(distributorId, no);
	}

	public List<Merchant> findAll() {
		return repository.findAll();
	}

}
